/*
 * Controller.java
 * Gavin Greene
 * Controller Class
 * 
 * Version 5/29/2011
 * Initial commit, added gui, basic writing out functionality
 * 
 * Version 5/30/2011
 * Added detection of different constraints, writes out to GUI.
 * 
 * Version 6/1/2011 
 * Added Output to file. Checked.
 */
package controller;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.List;
import java.util.Observable;
import java.util.Observer;

import javax.swing.JOptionPane;

import parsers.ScheduleParser;
import scheduleGenerator.ScheduleChecker;
import Constraint.ConstraintInfo;
import Constraint.Violations;
import businessRule.BusinessRuleViolation;
import data.ClassSlot;
import data.Database;
import data.TimeSlot;

/**
 * 
 * @author Gavin Greene
 * @version 5/28/2011
 * 
 *The controller creates a gui, takes in and creates files, checks schedule, and outputs the constraints.
 */
public class Controller implements Observer  {

	private static final String SEPERATER = "-------------------------";
	private static final String DEFAULT_PATH = "./";
	private static final String OUTPUTFILENAME = "ScheduleConstraints.txt";

	Database myDb;
	ScheduleParser myScheduleParser;
	ScheduleChecker myScheduleChecker;

	List<ClassSlot> myScheduleClasses;
	List<TimeSlot> myScheduleTimeSlots;
	gui myGui;

	File ScheduleFile;

	/**
	 * The controller for the Schedule Checker class.
	 */
	public Controller()
	{


		setupData();

		myGui = new gui();
		myGui.addObserver(this);

		//get schedule from scheduler checker, Write out constraints.
	}

	private void setupData(){
		try{
			myDb = new Database(DEFAULT_PATH);
		}
		catch(IOException e){
			JOptionPane.showMessageDialog(null,
					"exception " + e + "\n" + 
					" Please make sure you have write privilages " +
					"in the directory you run this program" ,
					"error",
					JOptionPane.ERROR_MESSAGE);
		}

	}

	private void printSchedulerChecking(ScheduleChecker theScheduleChecker){
		StringBuffer FileOutputBuffer = new StringBuffer();
		List<ConstraintInfo> constraintsMet = theScheduleChecker.getConstraintsMet();
		List<ConstraintInfo> constraintsViolated = theScheduleChecker.getConstraintsViolated();
		List<BusinessRuleViolation> BusinessRulesViolated = theScheduleChecker.getBusinessRulesViolated();

		myGui.ClearTextField();
		myGui.WriteTextField("Constraints:");
		FileOutputBuffer.append('\n' + "Constraints");
		myGui.WriteTextField(SEPERATER);
		FileOutputBuffer.append('\n' + SEPERATER);
		myGui.WriteTextField("Constraints Met:");
		FileOutputBuffer.append('\n' + "Constraints Met:" + '\n');

		for (ConstraintInfo constraint : constraintsMet){
			if(constraint.getTime() == null){
				String text = constraint.getUser().getName() + " got requestd class: " + constraint.getClassSlot().getClassTitle().toString();
				myGui.WriteTextField(text);
				FileOutputBuffer.append(text + '\n');
			}
			else{
				String text = constraint.getUser().getName() + " got requestd time slot: " + constraint.getTime().toString();
				myGui.WriteTextField(text);
				FileOutputBuffer.append(text + '\n');
			}
		}
		myGui.WriteTextField(SEPERATER);
		FileOutputBuffer.append(SEPERATER + '\n');
		myGui.WriteTextField("Constraints Violated");
		FileOutputBuffer.append("Constraints Violated:" + '\n');
		for (ConstraintInfo constraint : constraintsViolated){

			if(constraint.getViolation() == Violations.CLASSVIOLATION){
				String text = constraint.getUser().getName() + " did not get class: " + constraint.getClassSlot().getClassTitle().toString();
				myGui.WriteTextField(text);
				FileOutputBuffer.append(text + '\n');
			}
			else if(constraint.getViolation() == Violations.TEACHERNOTASSIGNED){
				String text = constraint.getUser().getName() + " Provided feedback, but was not assigned in the schedule ";
				myGui.WriteTextField(text);
				FileOutputBuffer.append(text + '\n');
			}
			else if(constraint.getViolation() == Violations.TIMEVIOLATION){
				String text = constraint.getUser().getName() + " did not get time slot: " + constraint.getTime().toString();
				myGui.WriteTextField(text);
				FileOutputBuffer.append(text + '\n');
			}
		}
		myGui.WriteTextField(SEPERATER);
		myGui.WriteTextField("Business Rules Violated:");
		FileOutputBuffer.append('\n' + SEPERATER);
		FileOutputBuffer.append('\n' +"Business Rules Violated:");

		for (BusinessRuleViolation rule : BusinessRulesViolated){
			String text = rule.getRuleViolated().getName() + rule.getUser();
			myGui.WriteTextField(text);
			FileOutputBuffer.append(text + '\n');
		}
		myGui.WriteTextField(SEPERATER);
		writeFile(FileOutputBuffer.toString());
	}

	private void checkSchedule(){

		myScheduleChecker = new ScheduleChecker(myScheduleClasses, myScheduleTimeSlots, myDb);
		printSchedulerChecking(myScheduleChecker);

	}

	/**
	 * Loads the file, initializes the hash table and graph. Catches b
	 * 
	 * @param the_fileName the file to load.
	 */
	private void Loadfile(String theFilename){ 
		try{
			myScheduleParser = new ScheduleParser(theFilename);
			List<ClassSlot> tempClassSlotList = myScheduleParser.getClassSlotList();
			List<TimeSlot> tempTimeSlotList = myScheduleParser.getTimeSlotList();
			if(tempClassSlotList.isEmpty() || tempTimeSlotList.isEmpty()){
				throw new IOException();
			}
			else{
				//we opened the file successfully:

				myGui.ClearTextField();
				myGui.WriteTextField("Loaded Schedule:"  + 
						" from file: " + theFilename);
				myScheduleClasses = tempClassSlotList;
				myScheduleTimeSlots = tempTimeSlotList;
				//For TESTING:

				for(ClassSlot c : myScheduleClasses){
					myGui.AppendTextField(c.getClassNum() + '\n');
				}
				for (TimeSlot t : myScheduleTimeSlots){

					myGui.AppendTextField(t.toString() + '\n');
				}
				//END TEST
				checkSchedule();
			}
		}catch(IOException e){
			JOptionPane.showMessageDialog(null,
					"Could not Open File: " + theFilename + "\n" + 
					" Please make sure it is a valid Schedule file" ,
					"error",
					JOptionPane.ERROR_MESSAGE);
			myGui.setFile(false);
		}
	}

	private void writeFile(String theText){
		File outputFile = new File(DEFAULT_PATH + 
				OUTPUTFILENAME);
		if(outputFile.exists()){
			//there is already a file here
			outputFile.delete();
		}
		try {
			//Open file
			FileWriter fw = new FileWriter(outputFile);
			BufferedWriter  br = new BufferedWriter(fw);
			br.write(theText);
			//write file

			br.flush();
			br.close();
			fw.close();
		} catch (IOException e) {
			
		}

	}

	/**
	 * This is to handle the events from the GUI. 
	 * it should only be called with a file as an argument.
	 */
	@Override
	public void update(Observable o, Object arg) {

		String theFileName = (String)arg;
		if(theFileName != null){
			Loadfile(theFileName);
		}

	}


	public static void main(String ... args){
		new Controller();
	}
}
